package com.smsc.headend.task.engine.service.push.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.smsc.headend.module.asset.entity.Meter;
import com.smsc.headend.module.data.dto.DataItemDTO;
import com.smsc.headend.module.data.entity.RdMeterReadsLp;
import com.smsc.headend.module.data.enums.CollectionSource;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.push.entity.ConfigNotifyType;
import com.smsc.headend.module.push.entity.ConfigNotifyTypeParam;
import com.smsc.headend.module.task.dto.TaskReadData;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.mapper.ConfigMeterTemplateMapper;
import com.smsc.headend.task.engine.po.DeviceDetail;
import com.smsc.headend.task.engine.service.DataProcessService;
import com.smsc.headend.task.engine.service.asset.AssetService;
import com.smsc.headend.task.engine.service.calc.RdEnergyDailyService;
import com.smsc.headend.task.engine.service.push.ConfigNotifyTypeParamService;
import com.smsc.headend.task.engine.service.push.PushDataDecodeHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * (业务实现)
 *
 * @author wjh
 * @date 2022/6/17 9:19.
 */
@Slf4j
public class GenericProfileDataHandlerImpl implements PushDataDecodeHandler {

    @Autowired
    DataProcessService dataProcessService;
    @Autowired
    ConfigMeterTemplateMapper configMeterTemplateMapper;
    @Autowired
    AssetService assetService;
    @Autowired
    RdEnergyDailyService rdEnergyDailyService;
    @Autowired
    ConfigNotifyTypeParamService paramService;

    @Override
    public void handler(CosemData cosemData, ConfigNotifyType configNotifyType, DeviceDetail deviceDetail, Long dataItemId, Date uploadDate) {
        if (null == dataItemId) {
            log.error("decode generic profile push data error,dataItemId is null");
            return;
        }
        Long meterId = deviceDetail.getDeviceId();
        Long lpDataItemId = dataItemId;
        Long lpTemplateId = configMeterTemplateMapper.getMeterTemplateId(meterId, "LOADPROFILE_TEMPLATE_ID");
        List<DataItemDTO> dataItemCosemList = dataProcessService.getLoadProfileCaptureObjects(null, lpDataItemId, meterId);
        if (CollectionUtil.isEmpty(dataItemCosemList)) {
            log.error("decode generic profile push data error,invalid Config Capture Objects");
            return;
        }
        log.debug("decode generic profile push data,capture objects {}", JSONUtil.toJsonStr(dataItemCosemList));
        List<ConfigNotifyTypeParam> params = paramService.getListByNotifyTypeId(configNotifyType.getNotifyTypeId());
        Map<String, ConfigNotifyTypeParam> paramMap = params
                .stream()
                .collect(Collectors.toMap(ConfigNotifyTypeParam::getParamName, e -> e));
        ConfigNotifyTypeParam childDataParam = paramMap.get("childData");
        CosemData childData;
        if(null ==childDataParam || StrUtil.isEmpty(childDataParam.getParamIndex())) {
            childData = cosemData;
        } else {
            childData = paramService.getCosemDataByIndex(cosemData, childDataParam.getParamIndex());
        }
        Meter meter = assetService.getMeterById(meterId);
        List<RdMeterReadsLp> meterReadsCol = new ArrayList<>();
        CollectionSource collectionSource = CollectionSource.PUSH;
        //获取数据
        try {
            if (CollUtil.isNotEmpty(childData.getChild())) {
                meterReadsCol = dataProcessService.getRdMeterReadLpList(childData, lpTemplateId, lpDataItemId, dataItemCosemList, meter, collectionSource);
            }
            //save profile data
            if(CollectionUtils.isEmpty(meterReadsCol)) {
                log.error("decode generic profile push data error,RdMeterReadsLp list is empty");
                return;
            }
            TaskReadData readData = new TaskReadData();
            readData.setTaskMeterReads(meterReadsCol);
            dataProcessService.saveTaskReadData(readData, collectionSource);
            //计算线损
            rdEnergyDailyService.calcDailyEnergyInterval(readData);
        } catch (UDISTaskHandlerException e) {
            log.error("decode generic profile push data error,{}",e.getErrorText());
        }
    }
}
